// 6. 接口（抽象类）
/**
 * 1. 概念
 *    + 接口描述了类的行为和功能，而不需要完成类的特定实现。
 *    + C++接口是使用抽象类来实现的，抽象类与数据抽象互不混淆，数据抽象是把实现细节和相关的数据（对外的方法、状态）分开的概念。
 * 
 * 2. #21 抽象类 （通常称为ABC）
 *    + 如果一个类中至少有一个函数被声明为纯虚函数，则这个类就是抽象类。
 *    + 抽象类不能用于实例化对象，只能作为接口使用。如果试图实例化一个抽象类的对象，会导致编译错误。
 *    + 如果一个抽象类的子类需要实例化，则必须实现每个虚函数，这也意味着C++支持使用抽象类声明接口。如果没有在派生类中重写虚函数，就尝试实例化该类对象，会导致编译错误。
 * 
 *    可用于实例化对象的类叫具体类。
 * 
 * 3. 抽象类的作用
 *    + 给其他类提供一个可以继承的适当的基类
 * 
 * 4. 设计决策
 *    + 面向对象的系统可能会使用一个抽象基类为所有的外部应用程序提供一个适当的、通用的、标准化的接口。然后，派生类通过继承抽象基类，就把所有类似的操作都继承下来。
 *    + 外部应用程序提供的功能（即公有函数）在抽象基类中是以纯虚函数的形式存在的。这些纯虚函数在相应的派生类中被实现。
 *    + 这个架构也使得新的应用程序可以很容易地被添加到系统中，即使是在系统被**定义之后**依然可以如此。
 * 
*/

#include <iostream>

#define __mark 21

#if 21 == __mark
/**
 * #21 抽象类
*/
class A
{
private:
  int a;

public:
  A() : a(0) {}
  virtual void func() = 0; // 定义纯虚函数，声明接口
};

class B : public A
{
private:
  int b;

public:
  B() : A(), b(0) {}
  void func()
  {
    std::cout << "B func()..." << std::endl;
  } // 重写实现基类纯虚函数
};
int main(void)
{
  // A a1;// 实例化抽象类报错
  B b1; // 未实现继承自抽象类的纯虚函数时，实例化子类报错
  b1.func();
  printf("-----------end-------------\n");
  return 0;
}
#elif 2 == __mark
int main(void)
{

  printf("-----------end-------------\n");
  return 0;
}
#endif
